package com.jyy.prefabricated.service;

import com.jyy.prefabricated.dto.ExamApplyDto;
import com.jyy.prefabricated.dto.PutStockDto;
import com.jyy.prefabricated.entity.*;
import com.jyy.prefabricated.enums.ApplyStatusEnum;
import com.jyy.prefabricated.enums.ExerciseStatusEnum;
import com.jyy.prefabricated.enums.OrderTypeEnum;
import com.jyy.prefabricated.enums.RelationTypeEnum;
import com.jyy.prefabricated.exception.CustomException;
import com.jyy.prefabricated.mapper.*;
import com.jyy.prefabricated.utils.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @version 1.0.0
 * @author: zjj
 */

@Service
public class TrainingOrganizationStockService {

    @Resource
    private TrainingOrganizationStockMapper trainingOrganizationStockMapper;

    @Resource
    private StudentMapper studentMapper;

    @Resource
    private StudentCourseMapper studentCourseMapper;

    @Resource
    private StudentCoursePackageMapper studentCoursePackageMapper;

    @Resource
    private StudentProjectMapper studentProjectMapper;

    @Resource
    private CourseMapper courseMapper;

    @Resource
    private CoursePackageMapper coursePackageMapper;

    @Resource
    private ProjectInfoMapper projectInfoMapper;

    @Resource
    private ExamApplyMapper examApplyMapper;

    @Resource
    private ExamApplyStudentMapper applyStudentMapper;

    @Resource
    private CoursePackageService coursePackageService;

    @Resource
    private StudentExerciseService studentExerciseService;

    @Resource
    private StudentExerciseMapper studentExerciseMapper;

    @Resource
    private ExamMapper examMapper;

    @Resource
    private OrderInfoMapper orderInfoMapper;


    /**
     * 新增
     *
     * @param trainingOrganizationStock
     * @return
     */
    public Integer insert(TrainingOrganizationStock trainingOrganizationStock) {
        trainingOrganizationStockMapper.insert(trainingOrganizationStock);
        return trainingOrganizationStock.getId();
    }

    /**
     * 更新
     *
     * @param trainingOrganizationStock
     * @return
     */
    public int update(TrainingOrganizationStock trainingOrganizationStock) {
        if (trainingOrganizationStock.getId() == null) {
            throw new CustomException("参数id不能为空");
        }
        return trainingOrganizationStockMapper.updateByPrimaryKeySelective(trainingOrganizationStock);
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    public int delete(Integer id) {
        return trainingOrganizationStockMapper.deleteByPrimaryKey(id);
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    public TrainingOrganizationStock selectById(Integer id) {
        TrainingOrganizationStock stock = trainingOrganizationStockMapper.selectByPrimaryKey(id);
        if (OrderTypeEnum.COURSE.getValue().equals(stock.getType())) {
            CourseWithBLOBs course = courseMapper.selectByPrimaryKey(stock.getProductId());
            stock.setLecturer(course.getLecturer());
            stock.setContent(course.getContent());
            stock.setPic(course.getPic());
        } else if (OrderTypeEnum.COURSE_PACKAGE.getValue().equals(stock.getType())) {
            CoursePackage coursePackage = coursePackageMapper.selectByPrimaryKey(stock.getProductId());
            stock.setContent(coursePackage.getContent());
            stock.setPic(coursePackage.getPic());
        } else if (OrderTypeEnum.Exam.getValue().equals(stock.getType())) {
            Exam exam = examMapper.selectByPrimaryKey(stock.getProductId());
            stock.setContent(exam.getContent());
            stock.setPic(exam.getPic());
        } else {
            ProjectInfo projectInfo = projectInfoMapper.selectByPrimaryKey(stock.getProductId());
            stock.setContent(projectInfo.getContent());
            stock.setPic(projectInfo.getPic());
        }
        return stock;
    }

    /**
     * 查询库存详情
     *
     * @param trainingOrganizationId 机构id
     * @param productId              产品id
     * @param type                   类型
     * @return
     */
    public TrainingOrganizationStock selectByTrainingOrganizationIdProductIdAndType(Integer trainingOrganizationId, Integer productId, Integer type) {
        return trainingOrganizationStockMapper.selectByTrainingOrganizationIdProductIdAndType(trainingOrganizationId, productId, type);
    }

    /**
     * 根据参数查询列表
     *
     * @param trainingOrganizationId   机构id
     * @param productName              产品名称
     * @param trainingOrganizationName 产品名称
     * @param type                     类型
     * @return
     */
    public List<TrainingOrganizationStock> selectByParams(String productName, Integer type, Integer trainingOrganizationId, String trainingOrganizationName) {
        List<TrainingOrganizationStock> result = trainingOrganizationStockMapper.selectByParams(productName, type, trainingOrganizationId, trainingOrganizationName);
        if (result != null && result.size() > 0) {
            for (TrainingOrganizationStock item : result) {
                if (item.getBuyType() != null && item.getPayTime() != null && item.getBuyTypeNum() != null) {
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    Calendar ca = Calendar.getInstance();
                    ca.setTime(item.getPayTime());
                    if (item.getBuyType() != null && item.getBuyTypeNum() != null) {
                        if (item.getBuyType() == 0) {
                            ca.add(Calendar.YEAR, item.getBuyTypeNum());
                        } else if (item.getBuyType() == 1) {
                            ca.add(Calendar.MONTH, item.getBuyTypeNum());
                        } else if (item.getBuyType() == 2) {
                            ca.add(Calendar.WEEK_OF_YEAR, item.getBuyTypeNum());
                        } else if (item.getBuyType() == 3) {
                            ca.add(Calendar.DATE, item.getBuyTypeNum());
                        }
                    }
                    item.setEndTime(ca.getTime());
                    long now = DateUtils.getUct8NowDate().getTime();
                    if (ca.getTime().getTime() < now) {
                        item.setWhetherOverdue(false);
                    }
                }
            }
        }

        return result;
    }


    /**
     * 根据参数查询练习列表
     *
     * @param stocks 库存课程包集合
     * @return
     */
    public List<ExamPaper> selectPracticeList(List<TrainingOrganizationStock> stocks) {
        List<ExamPaper> result = new ArrayList<>();
        if (stocks != null && stocks.size() > 0) {
            for (TrainingOrganizationStock trainingOrganizationStock : stocks) {
                CoursePackage coursePackage = coursePackageService.selectTree(trainingOrganizationStock.getProductId());
                //分配练习
                List<ExamPaper> practicesList = coursePackageService.findPractices(coursePackage);
                result.addAll(practicesList);
                //去重
                result = result.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(ExamPaper::getId))), ArrayList::new));
            }
        }
        return result;
    }
    /**
     * 查询可分配的学员列表
     *
     * @param stock
     * @return
     */
    public List<Student> selectStudentByStock(TrainingOrganizationStock stock) {
        if (OrderTypeEnum.COURSE.getValue().equals(stock.getType())) {
            return studentMapper.selectStudentByTrainingOrganizationIdAndCourseStock(stock.getTrainingOrganizationId(), stock.getProductId());
        } else if (OrderTypeEnum.COURSE_PACKAGE.getValue().equals(stock.getType())) {
            return studentMapper.selectStudentByTrainingOrganizationIdAndPackageStock(stock.getTrainingOrganizationId(), stock.getProductId());
        } else if (OrderTypeEnum.Exam.getValue().equals(stock.getType())) {
            return studentMapper.selectStudentByTrainingOrganizationIdAndExamStock(stock.getTrainingOrganizationId(), stock.getProductId());
        } else {
            return studentMapper.selectStudentByTrainingOrganizationIdAndProjectStock(stock.getTrainingOrganizationId(), stock.getProductId());
        }
    }

    /**
     * 分配课程到学员
     *
     * @param dto
     */
    public void putStock2Student(PutStockDto dto) {
        TrainingOrganizationStock stock = selectById(dto.getId());
        if (stock.getCurrentNum() < dto.getStudentIds().size()) {
            //判断库存是否足够
            throw new CustomException("当前库存不足，请购买后再分配");
        } else {
            if (OrderTypeEnum.COURSE.getValue() == stock.getType()) {
                List<StudentCourse> studentCourses = new ArrayList<>();
                for (Integer studentId : dto.getStudentIds()) {
                    //给学员分配课程
                    StudentCourse studentCourse = new StudentCourse();
                    studentCourse.setStudentId(studentId);
                    studentCourse.setCourseId(stock.getProductId());
                    studentCourse.setType(RelationTypeEnum.ALLOT.getValue());
                    studentCourses.add(studentCourse);
                }
                studentCourseMapper.batchInsert(studentCourses);

            } else if (OrderTypeEnum.COURSE_PACKAGE.getValue() == stock.getType()) {
                //给学员分配课程包
                List<StudentCoursePackage> studentCoursePackages = new ArrayList<>();
                for (Integer studentId : dto.getStudentIds()) {
                    //给学员分配课程包
                    StudentCoursePackage studentCoursePackage = new StudentCoursePackage();
                    studentCoursePackage.setStudentId(studentId);
                    studentCoursePackage.setPackageId(stock.getProductId());
                    studentCoursePackage.setType(RelationTypeEnum.ALLOT.getValue());
                    studentCoursePackage.setOrderId(stock.getOrderId());
                    studentCoursePackages.add(studentCoursePackage);

                    //给学员分配考试和练习
                    //查询该课程包下所包含的所有考试和练习，然后申请考试
                    //分配考试
                    CoursePackage coursePackage = coursePackageService.selectTree(stock.getProductId());
                    List<Exam> examList = coursePackageService.find(coursePackage);
                    //去重
                    examList = examList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Exam::getId))), ArrayList::new));

                    if (examList != null && examList.size() > 0) {

                        for (Exam exam : examList) {
                            ExamApply examApply = new ExamApply();
                            ExamApplyDto examApplyDto = new ExamApplyDto();

                            examApplyDto.setExamId(exam.getId());
                            List<Integer> studentIds = new ArrayList<>();
                            studentIds.add(studentId);
                            examApplyDto.setStudentIds(studentIds);
                            BeanUtils.copyProperties(examApplyDto, examApply);
                            examApply.setTrainingOrganizationId(stock.getTrainingOrganizationId());
                            //审核通过
                            examApply.setStatus(ApplyStatusEnum.SUCCESS.getValue());

                            examApplyMapper.insert(examApply);
                            saveApplyId2Student(examApplyDto, examApply.getId());
                        }
                    }
                    //分配练习
                    List<ExamPaper> practicesList = coursePackageService.findPractices(coursePackage);
                    if (practicesList != null && practicesList.size() > 0) {

                        for (ExamPaper examPaper : practicesList) {
                            StudentExercise studentExercise = new StudentExercise();
                            studentExercise.setStudentId(studentId);
                            studentExercise.setExerciseStatus(ExerciseStatusEnum.Four.getValue());
                            studentExercise.setExamPaperId(examPaper.getId());
                            studentExerciseMapper.insert(studentExercise);
                            Integer studentExerciseId = studentExercise.getId();

                            studentExerciseService.initExercisePaperDetailByExamPaperId(examPaper.getId(), studentExerciseId);
                        }
                    }

                }
                studentCoursePackageMapper.batchInsert(studentCoursePackages);
            } else if (OrderTypeEnum.PROJECT.getValue() == stock.getType()) {
                //给学员分配项目
                List<StudentProject> studentProjects = new ArrayList<>();
                for (Integer studentId : dto.getStudentIds()) {
                    //给学员分配课程
                    StudentProject studentProject = new StudentProject();
                    studentProject.setStudentId(studentId);
                    studentProject.setProjectId(stock.getProductId());
                    studentProject.setType(RelationTypeEnum.ALLOT.getValue());
                    studentProjects.add(studentProject);
                }
                studentProjectMapper.batchInsert(studentProjects);
            } else if (OrderTypeEnum.Exam.getValue() == stock.getType()) {
                //给学员分配考试

                for (Integer studentId : dto.getStudentIds()) {
                    ExamApply examApply = new ExamApply();
                    ExamApplyDto examApplyDto = new ExamApplyDto();

                    examApplyDto.setExamId(stock.getProductId());
                    List<Integer> studentIds = new ArrayList<>();
                    studentIds.add(studentId);
                    examApplyDto.setStudentIds(studentIds);
                    examApply.setTrainingOrganizationId(stock.getTrainingOrganizationId());

                    BeanUtils.copyProperties(examApplyDto, examApply);
                    //审核通过
                    examApply.setStatus(ApplyStatusEnum.SUCCESS.getValue());
                    examApplyMapper.insert(examApply);
                    saveApplyId2Student(examApplyDto, examApply.getId());

                }

            } else if (OrderTypeEnum.Practice.getValue() == stock.getType()) {
                //给学员分配练习
                for (Integer studentId : dto.getStudentIds()) {
                    StudentExercise studentExercise = new StudentExercise();
                    studentExercise.setStudentId(studentId);
                    studentExercise.setExerciseStatus(ExerciseStatusEnum.Four.getValue());
                    studentExercise.setExamPaperId(stock.getProductId());
                    studentExerciseMapper.insert(studentExercise);
                    Integer studentExerciseId = studentExercise.getId();

                    studentExerciseService.initExercisePaperDetailByExamPaperId(stock.getProductId(), studentExerciseId);

                }

            }

            stock.setCurrentNum(stock.getCurrentNum() - dto.getStudentIds().size());
            update(stock);
        }
    }

    /**
     * 保存申请和学员的绑定信息
     *
     * @param dto
     * @param id
     */
    public void saveApplyId2Student(ExamApplyDto dto, Integer id) {
        if (dto.getStudentIds().size() > 0) {
            List<ExamApplyStudent> applyStudents = new ArrayList<>();
            for (Integer studentId : dto.getStudentIds()) {
                ExamApplyStudent applyStudent = new ExamApplyStudent();
                applyStudent.setApplyId(id);
                applyStudent.setStudentId(studentId);
                applyStudents.add(applyStudent);
            }
            applyStudentMapper.batchInsert(applyStudents);
        }
    }

    //判断商品（课程包）是否过期
    public Boolean whetherOverdue(Integer orderId) {
        OrderInfo orderInfo = orderInfoMapper.selectByPrimaryKey(orderId);
        if (orderInfo != null && orderInfo.getPayTime() != null) {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {
                Date currdate = format.parse(orderInfo.getPayTime());
                Calendar ca = Calendar.getInstance();
                ca.setTime(currdate);
                if (orderInfo.getBuyType() != null && orderInfo.getBuyTypeNum() != null) {
                    if (orderInfo.getBuyType() == 0) {
                        ca.add(Calendar.YEAR, orderInfo.getBuyTypeNum());
                    } else if (orderInfo.getBuyType() == 1) {
                        ca.add(Calendar.MONTH, orderInfo.getBuyTypeNum());
                    } else if (orderInfo.getBuyType() == 2) {
                        ca.add(Calendar.WEEK_OF_YEAR, orderInfo.getBuyTypeNum());
                    } else if (orderInfo.getBuyType() == 3) {
                        ca.add(Calendar.DATE, orderInfo.getBuyTypeNum());
                    }
                }
                currdate = ca.getTime();
                long now = DateUtils.getUct8NowDate().getTime();
                if (currdate.getTime() < now) {
                    return false;
                }
            } catch (ParseException e) {
            }

        }
        return true;
    }
}
